﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace UnoGame
{
    public interface IDeck
    {
        int Count();
        void AddCard(ICard card);
        void Shuffle();
        ICard Draw();
        void PlayCard(ICard card);

        // Method for test
        List<ICard> GetExaustedCardList();
    }

    public class Deck : IDeck
    {
        private List<ICard> playableCards;
        private List<ICard> exaustedCards;

        public Deck()
        {
            exaustedCards = new List<ICard>();
            playableCards = new List<ICard>();
        }

        public void AddCard(ICard card)
        {
            playableCards.Add(card);
        }

        public int Count()
        {
            return playableCards.Count;
        }

        public void Shuffle()
        {
            if (!playableCards.Count.Equals(0)) return;
            playableCards = exaustedCards;
            exaustedCards.Clear();

            var provider = new RNGCryptoServiceProvider();
            var n = playableCards.Count;
            while (n > 1)
            {
                var box = new byte[1];
                do provider.GetBytes(box);
                while (!(box[0] < n * (Byte.MaxValue / n)));
                int k = (box[0] % n);
                n--;
                var value = playableCards[k];
                playableCards[k] = playableCards[n];
                playableCards[n] = value;
            }
        }

        public ICard Draw()
        {
            var tempReturn = playableCards.First();
            playableCards.Remove(tempReturn);
            return tempReturn;
        }

        public void PlayCard(ICard card)
        {
            exaustedCards.Add(card);
        }

        // Method for test
        public List<ICard> GetExaustedCardList()
        {
            return exaustedCards;
        }
    }
}
